package com.ruoyi.basic.service.impl;

import com.ruoyi.basic.domain.Column;
import com.ruoyi.basic.mapper.ColumnMapper;
import com.ruoyi.basic.service.IColumnService;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 栏目Service业务层处理
 *
 * @author ruoyi
 * @date 2025-01-22
 */
@Service
public class ColumnServiceImpl implements IColumnService {

    @Resource
    private ColumnMapper columnMapper;

    @Autowired
    private RedisCache redisCache;

    // 缓存key前缀
    private static final String COLUMN_LIST_KEY = "column:list";
    private static final String COLUMN_LIST_VALUE_KEY = "column:list:";
    private static final String COLUMN_INFO_KEY = "column:info:";
    // 缓存时间：1天（Integer类型）
    private static final Integer CACHE_TTL = 86400;

    /**
     * 查询栏目
     *
     * @param id 栏目主键
     * @return 栏目
     */
    @Override
    public Column selectColumnById(Long id) {
        // 尝试从缓存获取
        String cacheKey = COLUMN_INFO_KEY + id;
        Column column = redisCache.getCacheObject(cacheKey);
        if (column != null) {
            return column;
        }

        // 缓存未命中，从数据库查询
        column = columnMapper.selectColumnById(id);
        if (column != null) {
            // 存入缓存
            redisCache.setCacheObject(cacheKey, column, CACHE_TTL, TimeUnit.SECONDS);
        }
        return column;
    }

    /**
     * 查询栏目列表
     *
     * @param column 栏目
     * @return 栏目集合
     */
    @Override
    public List<Column> selectColumnList(Column column) {
        // 如果有查询条件，直接查数据库（不缓存带条件的查询）
        if (column != null &&
            (column.getName() != null || column.getStatus() != null ||
             column.getType() != null || column.getValue() != null)) {
            return columnMapper.selectColumnList(column);
        }

        // 尝试从缓存获取全量列表
        List<Column> columnList = redisCache.getCacheObject(COLUMN_LIST_KEY);
        if (columnList != null) {
            return columnList;
        }

        // 缓存未命中，从数据库查询
        columnList = columnMapper.selectColumnList(column);
        if (columnList != null && !columnList.isEmpty()) {
            // 存入缓存
            redisCache.setCacheObject(COLUMN_LIST_KEY, columnList, CACHE_TTL, TimeUnit.SECONDS);
        }
        return columnList;
    }

    /**
     * 查询栏目树结构列表
     *
     * @param column 栏目
     * @return 栏目树集合
     */
    @Override
    public List<TreeSelect> selectColumnTreeList(Column column) {
        List<Column> columns = selectColumnList(column);
        return buildColumnTreeSelect(columns);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param columns 栏目列表
     * @return 树结构列表
     */
    @Override
    public List<Column> buildColumnTree(List<Column> columns) {
        List<Column> returnList = new ArrayList<Column>();
        List<Integer> tempList = columns.stream().map(Column::getColumnId).collect(Collectors.toList());
        for (Column column : columns) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(column.getParentId())) {
                recursionFn(columns, column);
                returnList.add(column);
            }
        }
        if (returnList.isEmpty()) {
            returnList = columns;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param columns 栏目列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildColumnTreeSelect(List<Column> columns) {
        List<Column> columnTrees = buildColumnTree(columns);
        return columnTrees.stream().map(this::buildColumnTreeSelectNode).collect(Collectors.toList());
    }

    /**
     * 构建TreeSelect节点
     *
     * @param column 栏目
     * @return TreeSelect
     */
    private TreeSelect buildColumnTreeSelectNode(Column column) {
        TreeSelect treeSelect = new TreeSelect();
        treeSelect.setId(column.getColumnId().longValue());
        treeSelect.setLabel(column.getName());
        treeSelect.setDisabled(StringUtils.equals("1", column.getStatus()));
        if (column.getChildren() != null && !column.getChildren().isEmpty()) {
            treeSelect.setChildren(column.getChildren().stream().map(this::buildColumnTreeSelectNode).collect(Collectors.toList()));
        }
        return treeSelect;
    }

    /**
     * 是否存在栏目子节点
     *
     * @param columnId 栏目ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean hasChildByColumnId(Integer columnId) {
        int result = columnMapper.hasChildByColumnId(columnId);
        return result > 0;
    }

    /**
     * 新增栏目
     *
     * @param column 栏目
     * @return 结果
     */
    @Override
    public int insertColumn(Column column) {
        // 设置祖级列表
        if (column.getParentId() != null && column.getParentId() != 0) {
            Column parentColumn = columnMapper.selectColumnById(column.getParentId().longValue());
            if (parentColumn != null) {
                // 如果父栏目已停用，不允许新增子栏目
                if ("1".equals(parentColumn.getStatus())) {
                    throw new ServiceException("父栏目已停用，不允许新增");
                }
                // 设置ancestors: 父ancestors + "," + parentId
                column.setAncestors(parentColumn.getAncestors() + "," + column.getParentId());
            } else {
                column.setAncestors("0");
            }
        } else {
            // 顶级栏目
            column.setAncestors("0");
        }

        int result = columnMapper.insertColumn(column);
        if (result > 0) {
            // 清除列表缓存
            clearColumnCache();
        }
        return result;
    }

    /**
     * 修改栏目
     *
     * @param column 栏目
     * @return 结果
     */
    @Override
    public int updateColumn(Column column) {
        // 更新ancestors
        if (column.getParentId() != null) {
            Column newParentColumn = columnMapper.selectColumnById(column.getParentId().longValue());
            Column oldColumn = columnMapper.selectColumnById(column.getColumnId().longValue());

            if (StringUtils.isNotNull(newParentColumn) && StringUtils.isNotNull(oldColumn)) {
                String newAncestors = newParentColumn.getAncestors() + "," + newParentColumn.getColumnId();
                String oldAncestors = oldColumn.getAncestors();
                column.setAncestors(newAncestors);
                updateColumnChildren(column.getColumnId(), newAncestors, oldAncestors);
            }
        }

        int result = columnMapper.updateColumn(column);
        if (result > 0) {
            // 清除相关缓存
            clearColumnCache();
            // 清除单个栏目缓存
            if (column.getColumnId() != null) {
                redisCache.deleteObject(COLUMN_INFO_KEY + column.getColumnId());
            }
        }
        return result;
    }

    /**
     * 修改子元素关系
     *
     * @param columnId 被修改的栏目ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    private void updateColumnChildren(Integer columnId, String newAncestors, String oldAncestors) {
        List<Column> children = columnMapper.selectChildrenColumnById(columnId);
        for (Column child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            columnMapper.updateColumnChildren(children);
        }
    }

    /**
     * 批量删除栏目
     *
     * @param ids 需要删除的栏目主键集合
     * @return 结果
     */
    @Override
    public int deleteColumnByIds(Long[] ids) {
        // 检查是否存在子节点
        for (Long id : ids) {
            if (hasChildByColumnId(id.intValue())) {
                Column column = columnMapper.selectColumnById(id);
                throw new ServiceException(String.format("栏目【%s】存在子栏目，不允许删除", column.getName()));
            }
        }

        int result = columnMapper.deleteColumnByIds(ids);
        if (result > 0) {
            // 清除缓存
            clearColumnCache();
            // 清除单个栏目缓存
            for (Long id : ids) {
                redisCache.deleteObject(COLUMN_INFO_KEY + id);
            }
        }
        return result;
    }

    /**
     * 删除栏目信息
     *
     * @param id 栏目主键
     * @return 结果
     */
    @Override
    public int deleteColumnById(Long id) {
        // 检查是否存在子节点
        if (hasChildByColumnId(id.intValue())) {
            Column column = columnMapper.selectColumnById(id);
            throw new ServiceException(String.format("栏目【%s】存在子栏目，不允许删除", column.getName()));
        }

        int result = columnMapper.deleteColumnById(id);
        if (result > 0) {
            // 清除缓存
            clearColumnCache();
            redisCache.deleteObject(COLUMN_INFO_KEY + id);
        }
        return result;
    }

    /**
     * 修改栏目状态
     *
     * @param column 栏目
     * @return 结果
     */
    @Override
    public int changeStatus(Column column) {
        int result = columnMapper.updateColumn(column);
        if (result > 0) {
            // 清除缓存
            clearColumnCache();
            if (column.getColumnId() != null) {
                redisCache.deleteObject(COLUMN_INFO_KEY + column.getColumnId());
            }
        }
        return result;
    }

    @Override
    public List<Column> selectDistinctTags(String columnValue) {
        if(StringUtils.isEmpty(columnValue)){
            return new ArrayList<>();
        }
        // 构建缓存key
        String cacheKey = COLUMN_LIST_VALUE_KEY + (columnValue != null ? columnValue : "all");

        // 尝试从缓存获取
        List<Column> columnData = redisCache.getCacheObject(cacheKey);
        if (columnData != null) {
            return columnData;
        }
       List<Column>newList = columnMapper.selectDistinctTags(columnValue);
        if (newList != null && newList.size() > 0) {
            // 存入缓存
            redisCache.setCacheObject(cacheKey, newList, CACHE_TTL, TimeUnit.SECONDS);
        }else{
            return new ArrayList<>();
        }
        return newList;

    }

    /**
     * 清除栏目缓存
     */
    private void clearColumnCache() {
        redisCache.deleteObject(COLUMN_LIST_KEY);
        redisCache.deleteKeysByPrefix(COLUMN_LIST_VALUE_KEY+"*");
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<Column> list, Column t) {
        // 得到子节点列表
        List<Column> childList = getChildList(list, t);
        t.setChildren(childList);
        for (Column tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<Column> getChildList(List<Column> list, Column t) {
        List<Column> tlist = new ArrayList<Column>();
        for (Column n : list) {
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().equals(t.getColumnId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<Column> list, Column t) {
        return getChildList(list, t).size() > 0;
    }
}
